﻿' ****************************************************************************
' Copyright (C) 2009 Tony George
' 
' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation; either version 2 of the License, or
' (at your option) any later version.
' 
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
' 
' You should have received a copy of the GNU General Public License
' along with this program; if not, write to the Free Software
' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
'
' ****************************************************************************

Imports System.Text
Imports System.Xml
Public Class frmMain
    Dim folder_resources As String
    Dim folder_config As String
    Dim appPath As String
    Dim join_exe As String
    Dim folder_lang As String

    Dim stub_old As String
    Dim stub_temp As String
    Dim stub_new As String
    Dim configFile As String

    Dim selected_icon As String
    Dim ResHack As String = ""
    Dim UPX As String = ""
    Dim goRC As String
    Dim NirCmd As String

    Dim versionInfoTemplateFile As String
    Dim versionInfoRC As String
    Dim versionInfoRES As String

    Private CTRL As Boolean
    Private m_Dragging As Boolean

    Protected exp_BytesWritten As Regex
    Protected matches_BytesWritten As MatchCollection
    Protected exp_BytesTotal As Regex
    Protected matches_BytesTotal As MatchCollection

    Dim proc As New Process

    Private Success As Boolean
    Private Aborted As Boolean

#Region "    Localization"
    Sub LoadLang(ByVal LangFile As String, ByVal initialLoad As Boolean)
        Try
            If My.Computer.FileSystem.FileExists(LangFile) Then
                Dim txt As String = My.Computer.FileSystem.ReadAllText(LangFile)
                LoadDictionary(txt)
                For Each i As ToolStripMenuItem In tsLang.DropDownItems
                    If i.Tag.ToString() = LangFile Then
                        i.Checked = True
                    Else
                        i.Checked = False
                    End If
                Next
            End If
            ApplyLanguage(initialLoad)
        Catch ex As Exception
            LoadDictionary(My.Resources.English)
            ApplyLanguage(initialLoad)
            MsgBox(GetLangString("2118"), MsgBoxStyle.Critical)
        End Try
    End Sub

    Sub LoadDictionary(ByVal LangFileText As String)
        LangDict.Clear()

        Dim lines() As String = Split(LangFileText, vbNewLine)
        For Each line As String In lines
            If line.Trim <> "" Then
                If line.Chars(0) <> ";" Then
                    Dim sections() As String = Split(line, "=", 2)
                    LangDict.Add(sections(0).Trim, sections(1).Trim)
                End If
            End If
        Next
    End Sub

    Sub ApplyLanguage(ByVal initialLoad As Boolean)
        ReplaceString("1000", tabFiles)
        ReplaceString("1001", tabGeneral)
        ReplaceString("1003", tabIcon)
        ReplaceString("1007", tabAbout)
        ReplaceString("1008", tabVersionInfo)
        ReplaceString("1009", tabTasks)
        ReplaceString("1010", tabDialogs) '--------------------------

        ReplaceString("1100", tsFile)
        ReplaceString("1101", tsOptions)
        ReplaceString("1102", tsLang)
        ReplaceString("1103", tsAdd7z)
        ReplaceString("1104", tsLoadConfig)
        ReplaceString("1104", cmdLoadSettings)
        ReplaceString("1105", tsSaveConfig)
        ReplaceString("1105", cmdSaveSettings)
        ReplaceString("1106", tsGUIFont)
        ReplaceString("1107", cmdMakeSFX)
        ReplaceString("1108", tsRefreshIconCache)
        ReplaceString("1109", miQuickLoad)

        'txtFiles.Text = ""
        'AppendString("1200", txtFiles)
        'AppendString("1201", txtFiles)
        'AppendString("1202", txtFiles)

        ReplaceString("1300", tabExtractPath)
        ReplaceString("1300", lblExtractPath)
        ReplaceString("1301", chkTemporaryFolder)
        ReplaceString("1303", lblInstallPath) '----
        ReplaceString("1303", txtInstallPath) '----
        ReplaceString("1304", chkAllowPathEdit)

        ReplaceString("1305", lblOverwriteMode)
        cmbOverwriteMode.Items.Clear()
        cmbOverwriteMode.Items.Add(GetLangString("1306")) '----
        cmbOverwriteMode.Items.Add(GetLangString("1307")) '----
        cmbOverwriteMode.Items.Add(GetLangString("1308")) '----
        cmbOverwriteMode.SelectedIndex = 0
        ReplaceString("1309", chkShowProgress)
        ReplaceString("1310", chkSelfDelete)
        ReplaceString("1311", chkXPStyle)
        ReplaceString("1312", chkCompressStub)

        ReplaceString("1402", chkCancel)
        ReplaceString("1402", tabCancelPrompt)
        ReplaceString("1403", chkFinishMessage)
        ReplaceString("1403", tabFinishPrompt)

        ReplaceString("1401", chkBegin)
        ReplaceString("1401", tabBeginPrompt)
        ReplaceString("1404", lblBegin) '----
        ReplaceString("1404", txtBegin) '----


        ReplaceString("1409", lblExtractPathText)
        ReplaceString("1412", lblExtractPathText1) '----
        ReplaceString("1412", txtExtractPathText) '----

        ReplaceString("1405", txtCancel)
        ReplaceString("1405", lblCancel) '----

        ReplaceString("1406", txtFinishMessage)
        ReplaceString("1406", lblFinishMessage)

        ReplaceString("1408", lblTitle)
        ReplaceString("1411", txtTitle) '----
        ReplaceString("1411", lblTitle1) '----
        ReplaceString("1411", lblTitle2) '----
        ReplaceString("1411", lblTitle4) '----
        ReplaceString("1411", lblTitle5) '----

        ReplaceString("1410", lblExtractCancelText)
        ReplaceString("1413", txtExtractCancelText)
        ReplaceString("1413", lblExtractCancelText1)
        ReplaceString("1414", tabProgress)
        ReplaceString("1415", lblExtractTitleText)
        ReplaceString("1416", txtExtractTitleText)
        ReplaceString("1417", lblExtractDialogText)
        If GetLangString("1418") <> "" Then
            cmbProgressPercent.Items.Clear()
            cmbProgressPercent.Items.Add(GetLangString("1418"))
            cmbProgressPercent.Items.Add(GetLangString("1419"))
            cmbProgressPercent.Items.Add(GetLangString("1420"))
            cmbProgressPercent.SelectedIndex = 0
        End If
        ReplaceString("1421", chkProgressShowIcon)
        ReplaceString("1421", chkExtractPathShowIcon)
        ReplaceString("1422", chkHideTitleIcon)
        ReplaceString("1423", chkProgressDisableCancel)
        ReplaceString("1424", chkPromptShowSFXIcon)

        'ReplaceString("1500", grpSelectIcon)
        If ResHack = "" Then
            ReplaceString("2103", lblIcon1)
        Else
            ReplaceString("1501", lblIcon1)
        End If

        ReplaceString("2303", frmRun)
        ReplaceString("1600", frmRun.grpRunProgram)
        ReplaceString("1601", frmRun.lblProgram)
        ReplaceString("1602", frmRun.lblArgs)
        ReplaceString("1603", frmRun.chkNoWait)
        ReplaceString("1604", frmRun.chkHideConsoleWindows)

        ReplaceString("2304", frmDelete)
        ReplaceString("2304", frmDelete.grpDelete)
        ReplaceString("1605", frmDelete.lblDelete)

        ReplaceString("1700", frmShortcut)
        ReplaceString("1701", frmShortcut.grpLocation)
        ReplaceString("1702", frmShortcut.grpUser)
        ReplaceString("1703", frmShortcut.grpParams)
        ReplaceString("1704", frmShortcut.optDesktop)
        ReplaceString("1705", frmShortcut.optStartMenu)
        ReplaceString("1706", frmShortcut.optPrograms)
        ReplaceString("1707", frmShortcut.optStartup)
        ReplaceString("1708", frmShortcut.optUsersAll)
        ReplaceString("1709", frmShortcut.optUsersCurrent)
        ReplaceString("1710", frmShortcut.lblSource)
        ReplaceString("1711", frmShortcut.lblArgs)
        ReplaceString("1712", frmShortcut.lblName)
        ReplaceString("1713", frmShortcut.lblDescription)
        ReplaceString("1714", frmShortcut.lblFolder)
        ReplaceString("1715", frmShortcut.lblWorkDir)
        ReplaceString("1716", frmShortcut.lblIconFile)
        ReplaceString("1717", frmShortcut.lblIconIndex)

        ReplaceString("1800", frmVariables)
        ReplaceString("1801", frmVariables.lblName)
        ReplaceString("1802", frmVariables.lblValue)

        ReplaceString("2000", frmRun.cmdOK)
        ReplaceString("2000", frmShortcut.cmdOK)
        ReplaceString("2000", frmVariables.cmdOK)
        ReplaceString("2001", frmRun.cmdCancel)
        ReplaceString("2001", frmShortcut.cmdCancel)
        ReplaceString("2001", frmVariables.cmdCancel)
        ReplaceString("2002", frmRun.lbl1)
        ReplaceString("2002", frmDelete.lbl1)
        ReplaceString("2002", frmShortcut.lbl1)

        If ResHack = "" Then
            ReplaceString("2119", lblFieldName)
        Else
            ReplaceString("2200", lblFieldName)
        End If
        ReplaceString("2200", chFieldName)
        ReplaceString("2201", lblFieldValue)
        ReplaceString("2201", chFieldValue)

        ReplaceString("2300", frmAddTask)
        ReplaceString("2301", frmAddTask.grpTask)
        ReplaceString("2302", frmAddTask.optShortcut)
        ReplaceString("2303", frmAddTask.optRunProgram)
        ReplaceString("2304", frmAddTask.optDelete)
        ReplaceString("2305", frmAddTask.optSetEnvVar)
    End Sub

    Sub ReplaceString(ByVal StringID As String, ByRef ctrl As Control)
        Dim value As String = ""
        If LangDict.TryGetValue(StringID, value) Then
            ctrl.Text = value
        End If
    End Sub

    Sub ReplaceString(ByVal StringID As String, ByRef ctrl As ToolStripMenuItem)
        Dim value As String = ""
        If LangDict.TryGetValue(StringID, value) Then
            ctrl.Text = value
        End If
    End Sub

    Sub ReplaceString(ByVal StringID As String, ByRef ch As System.Windows.Forms.ColumnHeader)
        Dim value As String = ""
        If LangDict.TryGetValue(StringID, value) Then
            ch.Text = value
        End If
    End Sub
#End Region

#Region "    Form"
    Private Sub frmMain_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop
        Dim array() As String = e.Data.GetData(DataFormats.FileDrop)
        AddFiles(array)
    End Sub

    Private Sub frmMain_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragEnter
        If e.Data.GetDataPresent(DataFormats.FileDrop) Then
            e.Effect = DragDropEffects.Copy
        End If
    End Sub

    Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If proc IsNot Nothing Then
            Try
                proc.Kill()
            Catch ex As Exception
                '
            End Try
        End If
    End Sub

    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        LangDict = New Dictionary(Of String, String)

        LoadDictionary(My.Resources.English)
        ApplyLanguage(True)

        setExternalPaths()
        getIcons()
        'If ResHack <> "" Then

        'End If
        addMenuItems(Me.cmVar, Me.txtInstallPath)

        For Each File As String In My.Application.CommandLineArgs
            AddFile(File)
        Next File

        Dim i As ToolStripMenuItem
        For Each file As String In My.Computer.FileSystem.GetFiles(folder_lang, FileIO.SearchOption.SearchTopLevelOnly, "*.txt")
            i = tsLang.DropDownItems.Add(Path.GetFileNameWithoutExtension(file))
            i.CheckOnClick = True
            i.Tag = file
            AddHandler i.Click, AddressOf tsLang_Click
        Next

        For Each item As ToolStripMenuItem In tsLang.DropDownItems
            If item.Text = "English" Then
                item.Checked = True
            End If
        Next

        Dim family As String = GetSetting("7_ZIP_SFX_Maker", "Config", "GUIFontName", "MS Sans Serif")
        Dim size As Integer = CInt(GetSetting("7_ZIP_SFX_Maker", "Config", "GUIFontSize", "8"))
        Me.Font = New Font(family, size)
        frmRun.Font = New Font(family, size)
        frmVariables.Font = New Font(family, size)
        frmShortcut.Font = New Font(family, size)

        LoadLang(GetSetting("7_ZIP_SFX_Maker", "Config", "Language", ""), True)

        chFile.Width = lvFiles.Width - 30
        chTask.Width = lvTasks.Width - 30

        miQuickLoad.Tag = New PresetMenuItem(folder_config, AddressOf miQuickLoadItem_Click)
        AddHandler miQuickLoad.DropDownOpening, AddressOf PresetMenuItem_DropDownOpening

        If My.Computer.FileSystem.GetFiles(folder_config, FileIO.SearchOption.SearchAllSubDirectories, "*.xml").Count > 0 Then
            miQuickLoad.DropDownItems.Add("")
        End If
    End Sub

    Sub miQuickLoadItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim item As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)
        Dim p As PresetMenuItem = item.Tag
        LoadXMLFile(p.Path)
    End Sub

    Sub setExternalPaths()
        appPath = My.Application.Info.DirectoryPath
        folder_resources = Path.Combine(appPath, "Resources")
        folder_config = Path.Combine(appPath, "Config")
        folder_lang = Path.Combine(appPath, "Language")

        CreateFolder(folder_resources)
        CreateFolder(folder_config)
        CreateFolder(folder_lang)

        configFile = Path.Combine(appPath, "config.txt")
        stub_old = Path.Combine(folder_resources, "7ZSD.sfx")
        stub_temp = Path.Combine(folder_resources, "stub_temp.sfx")
        stub_new = Path.Combine(folder_resources, "stub_new.sfx")

        If My.Computer.FileSystem.GetFiles(appPath, FileIO.SearchOption.SearchAllSubDirectories, "ResHacker.exe").Count > 0 Then
            ResHack = My.Computer.FileSystem.GetFiles(appPath, FileIO.SearchOption.SearchAllSubDirectories, "ResHacker.exe")(0)
            SelectDefaultIcon()
        Else
            ResHack = ""
            MsgBox(GetLangString("2100") & vbNewLine & vbNewLine & GetLangString("2101"), MsgBoxStyle.Critical, GetLangString("2102"))
            Me.lvIcons.Enabled = False
            SelectDefaultIcon()
            Me.lblIcon1.Text = GetLangString("2103")

            lblFieldName.Text = GetLangString("2119")
            txtFieldName.Visible = False
            txtFieldValue.Visible = False
            lblFieldValue.Visible = False
            lvVersionString.Enabled = False
            cmdVersionStringAdd.Enabled = False
            cmdVersionStringRemove.Enabled = False
            cmdVersionStringClear.Enabled = False
        End If

        If My.Computer.FileSystem.GetFiles(appPath, FileIO.SearchOption.SearchAllSubDirectories, "upx.exe").Count > 0 Then
            UPX = My.Computer.FileSystem.GetFiles(appPath, FileIO.SearchOption.SearchAllSubDirectories, "upx.exe")(0)
        Else
            UPX = ""
            MsgBox(GetLangString("2104") & vbNewLine & vbNewLine & GetLangString("2101"), MsgBoxStyle.Critical, GetLangString("2102"))
            Me.chkCompressStub.Checked = False
            Me.chkCompressStub.Enabled = False
        End If

        If My.Computer.FileSystem.GetFiles(appPath, FileIO.SearchOption.SearchAllSubDirectories, "join.exe").Count > 0 Then
            join_exe = My.Computer.FileSystem.GetFiles(appPath, FileIO.SearchOption.SearchAllSubDirectories, "join.exe")(0)
        Else
            join_exe = ""
            MsgBox(GetLangString("2105") + "     ", MsgBoxStyle.Critical, GetLangString("2102"))
        End If

        goRC = Path.Combine(folder_resources, "gorc.exe")
        NirCmd = Path.Combine(folder_resources, "nircmd.exe")

        versionInfoTemplateFile = Path.Combine(folder_resources, "versionInfoTemplate.rc")
        versionInfoRC = Path.Combine(folder_resources, "versionInfo.rc")
        versionInfoRES = Path.Combine(folder_resources, "versionInfo.res")
    End Sub

    Sub CreateFolder(ByVal folder As String)
        If Not My.Computer.FileSystem.DirectoryExists(folder) Then
            My.Computer.FileSystem.CreateDirectory(folder)
        End If
    End Sub
#End Region

#Region "    Make SFX"
    Sub Start()
        MenuStrip1.Enabled = False

        cmdLoadSettings.Enabled = False
        cmdSaveSettings.Enabled = False
        cmdMakeSFX.Enabled = False

        tabIcon.Enabled = False
        tabDialogs.Enabled = False
        tabTasks.Enabled = False
        tabVersionInfo.Enabled = False
        tabAbout.Enabled = False

        cmdFilesAdd.Enabled = False
        cmdFilesRemove.Enabled = False
        cmdFilesClear.Enabled = False

        'Me.Cursor = Cursors.WaitCursor

        Me.tcMain.SelectedIndex = 0

        'reset icons
        For K = 0 To Me.lvFiles.Items.Count - 1
            Me.lvFiles.Items(K).ImageKey = "pngPause"
        Next K

        Aborted = False

        prepareSFX()

        Dim currentArchive As String
        For K = 0 To Me.lvFiles.Items.Count - 1

            If Aborted Then
                Me.lvFiles.Items(K).ImageKey = "pngCancel"
                Continue For
            End If

            currentArchive = Me.lvFiles.Items(K).Text
            Me.lvFiles.Items(K).ImageKey = "pngResume"

            Success = True
            makeSFX(currentArchive)

            If (Success And Not Aborted) Then
                Me.lvFiles.Items(K).ImageKey = "pngCheck"
            Else
                Me.lvFiles.Items(K).ImageKey = "pngCancel"
            End If
        Next K

        Me.prgMain.Position = 0
        Me.prgMain.Text = GetLangString("2112")

        deleteTemp()

        Me.Cursor = Cursors.Default


        MenuStrip1.Enabled = True

        cmdLoadSettings.Enabled = True
        cmdSaveSettings.Enabled = True
        cmdMakeSFX.Enabled = True

        tabIcon.Enabled = True
        tabDialogs.Enabled = True
        tabTasks.Enabled = True
        tabVersionInfo.Enabled = True
        tabAbout.Enabled = True

        cmdFilesAdd.Enabled = True
        cmdFilesRemove.Enabled = True
        cmdFilesClear.Enabled = True
    End Sub

    Sub prepareSFX()
        Me.prgMain.Text = GetLangString("2111")
        deleteTemp()
        prepareConfigFile()
        prepareStub()
    End Sub

    Sub makeSFX(ByVal archive As String)
        Me.prgMain.Position = 0
        Me.prgMain.Text = GetLangString("2113")

        Dim sfxFile As String = Path.ChangeExtension(archive, ".sfx.exe")

        proc = New Process
        With proc.StartInfo
            .FileName = join_exe
            .Arguments = """" & stub_new & """ " & """" & configFile & """ " & """" & archive & """ " & """" & sfxFile & """"
            .UseShellExecute = False
            .WindowStyle = ProcessWindowStyle.Hidden
            .CreateNoWindow = True
            .RedirectStandardOutput = True
        End With
        Clipboard.SetText(proc.StartInfo.Arguments)

        cmdAbort.Enabled = True

        proc.Start()

        Dim Line As String
        Dim written As Long = 0
        Dim total As Long = 0
        Do Until proc.HasExited
            If Aborted Then Continue Do

            Line = proc.StandardOutput.ReadLine.Trim()
            If Line.Contains("copied") Then
                Try
                    written = CInt(Line.Split(" ")(0).Split("/")(0))
                    total = CInt(Line.Split(" ")(0).Split("/")(1))
                    Me.prgMain.Position = Math.Floor((written / total) * 100)
                Catch ex As Exception
                    written = 0
                    written = 1
                End Try

                Me.prgMain.Text = Line
            ElseIf Line.Contains("Error") Then
                Success = False
            End If
            My.Application.DoEvents()
        Loop

        cmdAbort.Enabled = False

        proc = Nothing
    End Sub


    Sub deleteTemp()
        DeleteFileIfExists(stub_temp)
        DeleteFileIfExists(stub_new)
        DeleteFileIfExists(configFile)
        DeleteFileIfExists(versionInfoRC)
        DeleteFileIfExists(versionInfoRES)
    End Sub

    Sub DeleteFileIfExists(ByVal file As String)
        If My.Computer.FileSystem.FileExists(file) Then
            My.Computer.FileSystem.DeleteFile(file)
        End If
    End Sub

    Sub prepareConfigFile()
        Dim s As String = ""
        s += ";!@Install@!UTF-8!" + vbNewLine

        s += "Title=" & """" & Me.txtTitle.Text & """" & vbNewLine
        If Me.chkBegin.Checked Then
            s += "BeginPrompt=" & """" & Me.txtBegin.Text & """" & vbNewLine
        End If
        If Me.chkCancel.Checked Then
            s += "CancelPrompt=" & """" & Me.txtCancel.Text & """" & vbNewLine
        End If
        If Me.chkFinishMessage.Checked Then
            s += "FinishMessage=" & """" & Me.txtFinishMessage.Text & """" & vbNewLine
        End If

        If Me.chkShowProgress.Checked = False Then
            s += "Progress=" & """" & "no" & """" & vbNewLine
        Else
            If chkProgressDisableCancel.Checked Then
                s += "GUIMode=""1""" & vbNewLine
            Else
                s += "Progress=" & """" & "yes" & """" & vbNewLine
            End If
        End If

        If Me.chkSelfDelete.Checked Then
            s += "SelfDelete=" & """" & "1" & """" & vbNewLine
        End If

        Dim guiFlags As String = ""
        Select Case cmbProgressPercent.SelectedIndex
            Case 0
                'do nothing
            Case 1
                guiFlags += "+1"
            Case 2
                guiFlags += "+2"
            Case Else
                'do nothing
        End Select

        If chkProgressShowIcon.Checked Then
            guiFlags += "+32"
        End If
        If Me.chkXPStyle.Checked Then
            guiFlags += "+8"
        End If
        If Me.chkAllowPathEdit.Checked Then
            guiFlags += "+128"
        End If
        If chkCancel.Checked Then
            guiFlags += "+256"
        End If
        If chkHideTitleIcon.Checked Then
            guiFlags += "+512"
        End If
        If chkExtractPathShowIcon.Checked Then
            guiFlags += "+1024"
        End If
        If chkPromptShowSFXIcon.Checked Then
            guiFlags += "+2048"
        End If
        If guiFlags <> "" Then
            guiFlags = guiFlags.Remove(0, 1)
        End If
        s += "GUIFlags=" & """" & guiFlags & """" & vbNewLine

        Select Case cmbOverwriteMode.SelectedIndex
            Case 0 'all
                s += "OverwriteMode=" & """" & "0" & """" & vbNewLine
            Case 1 'none
                s += "OverwriteMode=" & """" & "1" & """" & vbNewLine
            Case 2 'older
                s += "OverwriteMode=" & """" & "2" & """" & vbNewLine
            Case Else 'all
                s += "OverwriteMode=" & """" & "0" & """" & vbNewLine
        End Select

        If chkTemporaryFolder.Checked Then
            s += "InstallPath=" & """%TEMP%""" & vbNewLine
        Else
            s += "InstallPath=" & """" & Me.txtInstallPath.Text & """" & vbNewLine
        End If

        s += "ExtractPathText=" & """" & Me.txtExtractPathText.Text & """" & vbNewLine
        s += "ExtractPathTitle=" & """" & Me.txtTitle.Text & """" & vbNewLine

        s += "ExtractTitle=" & """" & Me.txtExtractTitleText.Text & """" & vbNewLine
        s += "ExtractDialogText=" & """" & Me.txtExtractDialogText.Text & """" & vbNewLine
        s += "ExtractCancelText=" & """" & Me.txtExtractCancelText.Text & """" & vbNewLine

        For Each item As ListViewItem In Me.lvTasks.CheckedItems
            s += item.Text & vbNewLine
        Next item

        s += ";!@InstallEnd@!"
        My.Computer.FileSystem.WriteAllText(configFile, s, False, System.Text.Encoding.UTF8)
    End Sub

    Sub prepareStub()
        Dim s As String = ""
        Dim proc As New Process

        My.Computer.FileSystem.CopyFile(stub_old, stub_new)

        'replace icon ------------------

        If ResHack <> "" Then
            s = " -addoverwrite "
            s += """" & stub_old & """"
            s += ",""" & stub_temp & """"
            s += ",""" & selected_icon & """"
            s += ", ICONGROUP, 101, 0"

            proc.StartInfo.FileName = ResHack
            proc.StartInfo.Arguments = s
            proc.StartInfo.CreateNoWindow = True
            proc.StartInfo.UseShellExecute = False
            proc.Start()

            Do Until (proc.HasExited)
                My.Application.DoEvents()
            Loop

            If My.Computer.FileSystem.FileExists(stub_temp) Then
                My.Computer.FileSystem.MoveFile(stub_temp, stub_new, True)
            End If
        End If

        'add version header ------------------------------

        'note: if no items are checked, then the version info gets deleted

        If ResHack <> "" Then
            If My.Computer.FileSystem.FileExists(versionInfoTemplateFile) Then

                'modify SFX stub: Delete version info strings -------------------------

                s = " -delete "
                s += """" & stub_new & """"
                s += ",""" & stub_temp & """"
                s += ", VERSIONINFO, 1,"

                proc.StartInfo.FileName = ResHack
                proc.StartInfo.Arguments = s
                proc.StartInfo.CreateNoWindow = True
                proc.StartInfo.UseShellExecute = False
                proc.Start()

                Do Until (proc.HasExited)
                    My.Application.DoEvents()
                Loop

                If My.Computer.FileSystem.FileExists(stub_temp) Then
                    My.Computer.FileSystem.MoveFile(stub_temp, stub_new, True)
                End If

                If lvVersionString.CheckedItems.Count > 0 Then

                    'create RC script ------------------------

                    Dim versionInfo As String = My.Computer.FileSystem.ReadAllText(versionInfoTemplateFile)

                    Dim info As String = ""
                    For Each i As ListViewItem In lvVersionString.CheckedItems
                        info += "VALUE """ + i.Text + """, """ + i.SubItems(1).Text + """" + vbNewLine
                    Next
                    versionInfo = versionInfo.Replace("%VERSIONSTRINGS%", info)
                    My.Computer.FileSystem.WriteAllText(versionInfoRC, versionInfo, False)

                    'compile RES file ----------------------

                    s = " /r """ & versionInfoRES & """"
                    s += " """ & versionInfoRC & """"

                    proc.StartInfo.FileName = goRC
                    proc.StartInfo.Arguments = s
                    proc.StartInfo.CreateNoWindow = True
                    proc.StartInfo.UseShellExecute = False
                    proc.Start()

                    Do Until (proc.HasExited)
                        My.Application.DoEvents()
                    Loop

                    'modify SFX stub: Add new version info string -------------------------

                    s = " -addoverwrite "
                    s += """" & stub_new & """"
                    s += ",""" & stub_temp & """"
                    s += ",""" & versionInfoRES & """"
                    s += ", VERSIONINFO, 1,"

                    proc.StartInfo.FileName = ResHack
                    proc.StartInfo.Arguments = s
                    proc.StartInfo.CreateNoWindow = True
                    proc.StartInfo.UseShellExecute = False
                    proc.Start()

                    Do Until (proc.HasExited)
                        My.Application.DoEvents()
                    Loop

                    If My.Computer.FileSystem.FileExists(stub_temp) Then
                        My.Computer.FileSystem.MoveFile(stub_temp, stub_new, True)
                    End If
                End If
            End If
        End If

        'compress with UPX ---------------

        If Me.chkCompressStub.Checked Then
            s = "-9 -o """ & stub_new & """"
            s += " """ & stub_temp & """"

            proc.StartInfo.FileName = UPX
            proc.StartInfo.Arguments = s
            proc.StartInfo.CreateNoWindow = True
            proc.StartInfo.UseShellExecute = False
            proc.Start()

            Do Until (proc.HasExited)
                My.Application.DoEvents()
            Loop

            If My.Computer.FileSystem.FileExists(stub_temp) Then
                My.Computer.FileSystem.MoveFile(stub_temp, stub_new, True)
            End If
        End If
    End Sub
#End Region

#Region "    Files"
    Sub AddFile(ByVal archive As String)
        If Path.GetExtension(archive).ToLower <> ".7z" Then
            MsgBox(GetLangString("2106"))
            Exit Sub
        End If
        Me.lvFiles.Items.Add(archive).ImageKey = "pngPause"
    End Sub

    Sub AddFiles(ByVal array() As String)
        For Each archive As String In array
            AddFile(archive)
        Next archive
    End Sub

    Private Sub cmdFilesAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdFilesAdd.Click
        If Me.dlgAddFiles.ShowDialog = Windows.Forms.DialogResult.OK Then
            AddFiles(Me.dlgAddFiles.FileNames)
        End If
        Me.cmdFilesClear.Enabled = True
    End Sub

    Private Sub cmdFilesRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdFilesRemove.Click
        Dim selectedItems As New List(Of ListViewItem)

        For Each lvi As ListViewItem In lvFiles.SelectedItems
            selectedItems.Add(lvi)
        Next

        For Each lvi As ListViewItem In selectedItems
            lvFiles.Items.Remove(lvi)
        Next
    End Sub

    Private Sub cmdFilesClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdFilesClear.Click
        lvFiles.Items.Clear()
        'Me.cmdFilesRemove.Enabled = False
        'Me.cmdFilesClear.Enabled = False
        'Me.cmdMakeSFX.Enabled = False
    End Sub

    Private Sub lstFiles_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        'If Me.lstFiles.SelectedItems.Count > 0 Then
        '    Me.cmdFilesRemove.Enabled = True
        'Else
        '    Me.cmdFilesRemove.Enabled = False
        'End If
    End Sub
#End Region

#Region "    Tasks"
    Private Sub cmdAddTask_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAddTask.Click
        SelectedTask = Nothing
        frmAddTask.ShowDialog()
    End Sub

    Private Sub cmdRemoveTask_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRemoveTask.Click
        Dim selectedItems As New List(Of ListViewItem)

        For Each lvi As ListViewItem In lvTasks.SelectedItems
            selectedItems.Add(lvi)
        Next

        For Each lvi As ListViewItem In selectedItems
            lvTasks.Items.Remove(lvi)
        Next
    End Sub

    Private Sub cmdClearTasks_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdClearTasks.Click
        Me.lvTasks.Items.Clear()
    End Sub

    Private Sub lvTasks_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lvTasks.DoubleClick
        If Me.lvTasks.SelectedItems.Count > 0 Then
            SelectedTask = lvTasks.SelectedItems(0)

            If SelectedTask.Text.Contains("Shortcut=") Then
                frmShortcut.ShowDialog()
            ElseIf SelectedTask.Text.Contains("RunProgram=") Then
                frmRun.ShowDialog()
            ElseIf SelectedTask.Text.Contains("Delete=") Then
                frmDelete.ShowDialog()
            Else
                frmVariables.ShowDialog()
            End If
        End If
    End Sub
#End Region

#Region "    VersionString"
    Private Sub cmdVersionStringAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdVersionStringAdd.Click
        lvVersionString.Items.Add("New Field").SubItems.Add("(Edit this)")
    End Sub

    Private Sub cmdVersionStringRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdVersionStringRemove.Click
        Dim selectedItems As New List(Of ListViewItem)

        For Each lvi As ListViewItem In lvVersionString.SelectedItems
            selectedItems.Add(lvi)
        Next

        For Each lvi As ListViewItem In selectedItems
            lvVersionString.Items.Remove(lvi)
        Next
    End Sub

    Private Sub cmdVersionStringClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdVersionStringClear.Click
        Me.lvVersionString.Items.Clear()
    End Sub

    Private Sub lvVersionString_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lvVersionString.SelectedIndexChanged
        RemoveHandler txtFieldName.TextChanged, AddressOf txtFieldName_TextChanged
        RemoveHandler txtFieldValue.TextChanged, AddressOf txtFieldValue_TextChanged

        If lvVersionString.SelectedItems.Count = 1 Then
            txtFieldName.Enabled = True
            txtFieldValue.Enabled = True
            txtFieldName.Text = lvVersionString.SelectedItems(0).Text
            txtFieldValue.Text = lvVersionString.SelectedItems(0).SubItems(1).Text

            For Each i As ListViewItem In lvVersionString.Items
                i.Font = New Font(i.Font, FontStyle.Regular)
            Next
            lvVersionString.SelectedItems(0).Font = New Font(lvVersionString.SelectedItems(0).Font, FontStyle.Bold)

            AddHandler txtFieldName.TextChanged, AddressOf txtFieldName_TextChanged
            AddHandler txtFieldValue.TextChanged, AddressOf txtFieldValue_TextChanged
        Else
            txtFieldName.Enabled = False
            txtFieldValue.Enabled = False
            txtFieldName.Text = ""
            txtFieldValue.Text = ""

            For Each i As ListViewItem In lvVersionString.Items
                i.Font = New Font(i.Font, FontStyle.Regular)
            Next
        End If
    End Sub

    Private Sub txtFieldName_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        If lvVersionString.SelectedItems.Count = 1 Then
            lvVersionString.SelectedItems(0).Text = txtFieldName.Text
        End If
    End Sub

    Private Sub txtFieldValue_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        If lvVersionString.SelectedItems.Count = 1 Then
            lvVersionString.SelectedItems(0).SubItems(1).Text = txtFieldValue.Text
        End If
    End Sub
#End Region

#Region "    Presets"
    Sub SaveXML()
        Me.dlgSaveSettings.InitialDirectory = folder_config
        If Me.dlgSaveSettings.ShowDialog = Windows.Forms.DialogResult.OK Then
            SaveXMLFile(Me.dlgSaveSettings.FileName)
        End If
    End Sub

    Sub SaveXMLFile(ByVal file As String)
        Dim doc As New XmlDocument
        Dim dec As XmlDeclaration = doc.CreateXmlDeclaration("1.0", Nothing, Nothing)
        doc.AppendChild(dec)
        Dim root As XmlElement = doc.CreateElement("Settings")
        doc.AppendChild(root)
        Dim general As XmlElement = doc.CreateElement("General")
        root.AppendChild(general)

        Dim node As XmlNode

        If (Me.chkTemporaryFolder.Checked) Then
            MakeXmlNode(general, "ExtractMode", "Temp")
        Else
            node = MakeXmlNode(general, "ExtractMode", "Custom")
            MakeXmlNodeAttribute(node, "Path", Me.txtInstallPath.Text)
            MakeXmlNodeAttribute(node, "AllowEdit", Me.chkAllowPathEdit.Checked.ToString)
        End If

        MakeXmlNode(general, "HideProgress", (Not Me.chkShowProgress.Checked).ToString)
        MakeXmlNode(general, "ProgressDisableCancel", Me.chkProgressDisableCancel.Checked.ToString)
        MakeXmlNode(general, "SelfDelete", Me.chkSelfDelete.Checked.ToString)
        MakeXmlNode(general, "CompressStub", Me.chkCompressStub.Checked.ToString)
        MakeXmlNode(general, "XPStyles", Me.chkXPStyle.Checked.ToString)
        MakeXmlNode(general, "HideTitleIcon", Me.chkHideTitleIcon.Checked.ToString)
        MakeXmlNode(general, "PromptShowSFXIcon", Me.chkPromptShowSFXIcon.Checked.ToString)

        Select Case cmbOverwriteMode.SelectedIndex
            Case 0 'all
                MakeXmlNode(general, "Overwrite", "All")
            Case 1 'none
                MakeXmlNode(general, "Overwrite", "None")
            Case 2 'older
                MakeXmlNode(general, "Overwrite", "Older")
            Case Else 'all
                MakeXmlNode(general, "Overwrite", "All")
        End Select

        node = MakeXmlNode(general, "MessageBegin", Me.txtBegin.Text)
        MakeXmlNodeAttribute(node, "Show", Me.chkBegin.Checked.ToString)

        node = MakeXmlNode(general, "MessageCancel", Me.txtCancel.Text)
        MakeXmlNodeAttribute(node, "Show", Me.chkCancel.Checked.ToString)

        node = MakeXmlNode(general, "MessageFinish", Me.txtFinishMessage.Text)
        MakeXmlNodeAttribute(node, "Show", Me.chkFinishMessage.Checked.ToString)

        MakeXmlNode(general, "TitleText", Me.txtTitle.Text)
        MakeXmlNode(general, "ExtractPathText", Me.txtExtractPathText.Text)
        MakeXmlNode(general, "ExtractCancelText", Me.txtExtractCancelText.Text)
        MakeXmlNode(general, "ExtractDialogText", Me.txtExtractDialogText.Text)
        MakeXmlNode(general, "ExtractTitleText", Me.txtExtractTitleText.Text)
        MakeXmlNode(general, "ExtractShowIcon", chkExtractPathShowIcon.Checked.ToString)

        MakeXmlNode(general, "ProgressPercent", Me.cmbProgressPercent.SelectedIndex)
        MakeXmlNode(general, "ProgressShowIcon", chkProgressShowIcon.Checked.ToString)
        MakeXmlNode(general, "Icon", selected_icon)

        Dim tasks As XmlElement = doc.CreateElement("Tasks")
        root.AppendChild(tasks)
        For Each lvi As ListViewItem In Me.lvTasks.Items
            node = MakeXmlNode(tasks, "Item", lvi.Text)
            MakeXmlNodeAttribute(node, "Enabled", lvi.Checked)
        Next lvi

        Dim verString As XmlElement = doc.CreateElement("VersionString")
        root.AppendChild(verString)
        For Each lvi As ListViewItem In Me.lvVersionString.Items
            node = MakeXmlNode(verString, "Item", "")
            MakeXmlNodeAttribute(node, "Name", lvi.Text)
            MakeXmlNodeAttribute(node, "Value", lvi.SubItems(1).Text)
            MakeXmlNodeAttribute(node, "Enabled", lvi.Checked)
        Next lvi

        doc.Save(file)
    End Sub

    Sub LoadXML()
        Me.dlgLoadSettings.InitialDirectory = folder_config
        If Me.dlgLoadSettings.ShowDialog = Windows.Forms.DialogResult.OK Then
            LoadXMLFile(dlgLoadSettings.FileName)
        End If
    End Sub

    Sub LoadXMLFile(ByVal file As String)
        Dim doc As New XmlDocument
        Dim node As XmlNode
        Dim s As String = ""

        doc.Load(file)

        node = doc.SelectSingleNode("/Settings/General/ExtractMode")
        Select Case node.InnerText
            Case "Temp"
                Me.chkTemporaryFolder.Checked = True
            Case "Custom"
                Me.chkTemporaryFolder.Checked = False
                Me.txtInstallPath.Text = AttributeValue(node, "Path", "C:\New Folder")
                Me.chkAllowPathEdit.Checked = Boolean.Parse(AttributeValue(node, "AllowEdit", "True"))
            Case Else
                Me.chkTemporaryFolder.Checked = False
                Me.txtInstallPath.Text = "C:\New Folder"
                Me.chkAllowPathEdit.Checked = True
        End Select

        node = doc.SelectSingleNode("/Settings/General/HideProgress")
        If node IsNot Nothing Then
            Me.chkShowProgress.Checked = Not Boolean.Parse(node.InnerText)
        End If

        node = doc.SelectSingleNode("/Settings/General/ProgressDisableCancel")
        If node IsNot Nothing Then
            Me.chkProgressDisableCancel.Checked = Boolean.Parse(node.InnerText)
        End If

        node = doc.SelectSingleNode("/Settings/General/SelfDelete")
        If node IsNot Nothing Then
            Me.chkSelfDelete.Checked = Boolean.Parse(node.InnerText)
        End If

        node = doc.SelectSingleNode("/Settings/General/CompressStub")
        If node IsNot Nothing Then
            Me.chkCompressStub.Checked = Boolean.Parse(node.InnerText)
        End If

        node = doc.SelectSingleNode("/Settings/General/XPStyles")
        If node IsNot Nothing Then
            Me.chkXPStyle.Checked = Boolean.Parse(node.InnerText)
        End If

        node = doc.SelectSingleNode("/Settings/General/HideTitleIcon")
        If node IsNot Nothing Then
            Me.chkHideTitleIcon.Checked = Boolean.Parse(node.InnerText)
        End If

        node = doc.SelectSingleNode("/Settings/General/PromptShowSFXIcon")
        If node IsNot Nothing Then
            Me.chkPromptShowSFXIcon.Checked = Boolean.Parse(node.InnerText)
        End If

        node = doc.SelectSingleNode("/Settings/General/Overwrite")
        If node IsNot Nothing Then
            Select Case node.InnerText
                Case "All"
                    cmbOverwriteMode.SelectedIndex = 0
                Case "None"
                    cmbOverwriteMode.SelectedIndex = 1
                Case "Older"
                    cmbOverwriteMode.SelectedIndex = 2
                Case Else
                    cmbOverwriteMode.SelectedIndex = 0
            End Select
        End If

        node = doc.SelectSingleNode("/Settings/General/MessageBegin")
        If node IsNot Nothing Then
            Me.txtBegin.Text = node.InnerText
            Me.chkBegin.Checked = Boolean.Parse(AttributeValue(node, "Show", "False"))
        End If

        node = doc.SelectSingleNode("/Settings/General/MessageCancel")
        If node IsNot Nothing Then
            Me.txtCancel.Text = node.InnerText
            Me.chkCancel.Checked = Boolean.Parse(AttributeValue(node, "Show", "False"))
        End If

        node = doc.SelectSingleNode("/Settings/General/MessageFinish")
        If node IsNot Nothing Then
            Me.txtFinishMessage.Text = node.InnerText
            Me.chkFinishMessage.Checked = Boolean.Parse(AttributeValue(node, "Show", "False"))
        End If

        node = doc.SelectSingleNode("/Settings/General/ProgressPercent")
        If node IsNot Nothing Then
            cmbProgressPercent.SelectedIndex = Integer.Parse(node.InnerText)
        End If

        node = doc.SelectSingleNode("/Settings/General/ProgressShowIcon")
        If node IsNot Nothing Then
            chkProgressShowIcon.Checked = Boolean.Parse(node.InnerText)
        End If

        node = doc.SelectSingleNode("/Settings/General/TitleText")
        If node IsNot Nothing Then
            Me.txtTitle.Text = node.InnerText
        End If

        node = doc.SelectSingleNode("/Settings/General/ExtractPathText")
        If node IsNot Nothing Then
            Me.txtExtractPathText.Text = node.InnerText
        End If

        node = doc.SelectSingleNode("/Settings/General/ExtractCancelText")
        If node IsNot Nothing Then
            Me.txtExtractCancelText.Text = node.InnerText
        End If

        node = doc.SelectSingleNode("/Settings/General/ExtractTitleText")
        If node IsNot Nothing Then
            Me.txtExtractTitleText.Text = node.InnerText
        End If

        node = doc.SelectSingleNode("/Settings/General/ExtractDialogText")
        If node IsNot Nothing Then
            Me.txtExtractDialogText.Text = node.InnerText
        End If

        node = doc.SelectSingleNode("/Settings/General/ExtractShowIcon")
        If node IsNot Nothing Then
            chkExtractPathShowIcon.Checked = Boolean.Parse(node.InnerText)
        End If

        If ResHack <> "" Then
            node = doc.SelectSingleNode("/Settings/General/Icon")
            If node IsNot Nothing Then
                If My.Computer.FileSystem.FileExists(node.InnerText) Then
                    SelectIcon(node.InnerText)
                End If
            End If
        End If

        Dim lvi As ListViewItem

        Me.lvTasks.Items.Clear()
        For Each n As XmlNode In doc.SelectNodes("/Settings/Tasks/Item")
            lvi = Me.lvTasks.Items.Add(n.InnerText)
            lvi.Checked = Boolean.Parse(n.Attributes("Enabled").Value)
        Next n

        'for compatibility with versions <= 2.2  -----------------

        For Each n As XmlNode In doc.SelectNodes("/Settings/Shortcuts/Item")
            Me.lvTasks.Items.Add(n.InnerText).Checked = True
        Next n

        For Each n As XmlNode In doc.SelectNodes("/Settings/EnvVariables/Item")
            Me.lvTasks.Items.Add(n.InnerText).Checked = True
        Next n

        For Each n As XmlNode In doc.SelectNodes("/Settings/RunPrograms/Item")
            Me.lvTasks.Items.Add(n.InnerText).Checked = True
        Next n

        '----------------------------------------------------

        Me.lvVersionString.Items.Clear()
        For Each n As XmlNode In doc.SelectNodes("/Settings/VersionString/Item")
            lvi = Me.lvVersionString.Items.Add(n.Attributes("Name").Value)
            lvi.SubItems.Add(n.Attributes("Value").Value)
            If n.Attributes("Enabled") IsNot Nothing Then 'for compatibility with versions <= 2.2 
                lvi.Checked = Boolean.Parse(n.Attributes("Enabled").Value)
            End If
        Next n
    End Sub

    Private Sub cmdLoadSettings_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLoadSettings.Click
        LoadXML()
    End Sub

    Private Sub cmdSaveSettings_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSaveSettings.Click
        SaveXML()
    End Sub
#End Region

#Region "    Selections"
    Sub getIcons()
        Dim first As Boolean = True
        For Each ico As String In My.Computer.FileSystem.GetFiles(folder_resources, FileIO.SearchOption.SearchTopLevelOnly, "*.ico")
            LoadNewIcon(ico)
        Next ico

        SelectDefaultIcon()
    End Sub

    Sub LoadNewIcon(ByVal iconFile As String)
        Dim found As Boolean = False
        For Each lvi As ListViewItem In lvIcons.Items
            If lvi.Tag.ToString.ToLower = iconFile.ToLower Then
                found = True
                Exit For
            End If
        Next

        If Not found Then
            Dim lvi As ListViewItem
            Dim icon As New Icon(iconFile, 48, 48)
            imglIcons.Images.Add("", icon)
            lvi = lvIcons.Items.Add("")
            lvi.ImageIndex = lvIcons.Items.Count - 1
            lvi.Tag = iconFile
        End If
    End Sub

    Sub SelectIcon(ByVal iconFile As String)
        LoadNewIcon(iconFile) 'add to list if not already there

        If ResHack = "" Then
            SelectDefaultIcon()
        Else
            selected_icon = iconFile

            'get image index
            Dim imageIndex As Integer = -1
            For Each lvi As ListViewItem In lvIcons.Items
                If lvi.Tag.ToString.ToLower = iconFile.ToLower Then
                    imageIndex = lvIcons.Items.IndexOf(lvi)
                    Exit For
                End If
            Next

            'set imagelist and index
            lvSelectedIcon.LargeImageList = imglIcons
            lvSelectedIcon.Items(0).ImageIndex = imageIndex
        End If
    End Sub

    Sub SelectDefaultIcon()
        selected_icon = ""

        'set imagelist and index
        lvSelectedIcon.LargeImageList = imglDefaultIcon
        lvSelectedIcon.Items(0).ImageIndex = 0
    End Sub

    Private Sub chkTemporaryFolder_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkTemporaryFolder.CheckedChanged
        Me.txtInstallPath.Enabled = Not chkTemporaryFolder.Checked

        If chkTemporaryFolder.Checked Then
            lblInstallPath.Text = "%TEMP%"
        Else
            lblInstallPath.Text = txtInstallPath.Text
        End If
    End Sub

    Private Sub chkBegin_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkBegin.CheckedChanged
        Me.txtBegin.Enabled = Me.chkBegin.Checked
    End Sub

    Private Sub chkCancel_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkCancel.CheckedChanged
        Me.txtCancel.Enabled = Me.chkCancel.Checked
    End Sub

    Private Sub chkFinish_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkFinishMessage.CheckedChanged
        Me.txtFinishMessage.Enabled = Me.chkFinishMessage.Checked
    End Sub

    Private Sub cmdMakeSFX_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdMakeSFX.Click
        If lvFiles.Items.Count > 0 Then
            Start()
        Else
            MsgBox(GetLangString("2107") & vbNewLine & GetLangString("2108") & vbNewLine & GetLangString("2109"), MsgBoxStyle.Exclamation, GetLangString("2110"))
        End If
    End Sub

    Private Sub lvIcons_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lvIcons.SelectedIndexChanged
        If lvIcons.SelectedItems.Count > 0 Then
            Dim ico As String = lvIcons.SelectedItems(0).Tag
            SelectIcon(ico)
        End If
    End Sub
#End Region

#Region "    Menu"
    Private Sub tsAdd7z_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsAdd7z.Click
        If dlgAddFiles.ShowDialog = Windows.Forms.DialogResult.OK Then
            AddFiles(dlgAddFiles.FileNames)
        End If
    End Sub

    Private Sub tsSaveConfig_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsSaveConfig.Click
        SaveXML()
    End Sub

    Private Sub tsLoadConfig_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsLoadConfig.Click
        LoadXML()
    End Sub

    Private Sub tsGUIFont_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsGUIFont.Click
        If dlgGUIFont.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.Font = dlgGUIFont.Font
            frmVariables.Font = dlgGUIFont.Font
            frmRun.Font = dlgGUIFont.Font
            frmShortcut.Font = dlgGUIFont.Font
            SaveSetting("7_ZIP_SFX_Maker", "Config", "GUIFontName", Me.Font.FontFamily.Name.ToString)
            SaveSetting("7_ZIP_SFX_Maker", "Config", "GUIFontSize", Me.Font.SizeInPoints.ToString)
        End If
    End Sub

    Private Sub tsRefreshIconCache_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsRefreshIconCache.Click
        Dim proc As New Process
        With proc.StartInfo
            .FileName = NirCmd
            .Arguments = "shellrefresh"
            .UseShellExecute = False
            .WindowStyle = ProcessWindowStyle.Hidden
            .CreateNoWindow = True
        End With
        proc.Start()
    End Sub

    Private Sub tsLang_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim ts As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)
        Dim file As String = ts.Tag

        For Each i As ToolStripMenuItem In tsLang.DropDownItems
            i.Checked = False
        Next
        ts.Checked = True

        LoadLang(file, False)

        SaveSetting("7_ZIP_SFX_Maker", "Config", "Language", file)
    End Sub
#End Region

#Region "    Task Listview"
    Private Sub lvTasks_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles lvTasks.DragDrop
        Dim lv As ListView = DirectCast(sender, ListView)

        'Return if the items are not selected in the ListView control.
        If lv.SelectedItems.Count = 0 Then Return

        'Returns the location of the mouse pointer in the ListView control.
        Dim p As Point = lv.PointToClient(New Point(e.X, e.Y))

        'Obtain the item that is located at the specified location of the mouse pointer.
        Dim dragToItem As ListViewItem = lv.GetItemAt(p.X, p.Y)

        'Obtain the index of the item at the mouse pointer.
        Dim dragIndex As Integer = 0
        If dragToItem IsNot Nothing Then
            dragIndex = dragToItem.Index
        Else
            dragIndex = lv.Items.Count
        End If

        'Get list of items selected in source list
        Dim sel(lv.SelectedItems.Count) As ListViewItem
        For i As Integer = 0 To lv.SelectedItems.Count - 1
            sel(i) = lv.SelectedItems.Item(i)
        Next

        Dim itemIndex As Integer = dragIndex
        For i = 0 To lv.SelectedItems.Count - 1
            'Obtain the ListViewItem to be dragged to the target location.
            Dim dragItem As ListViewItem = sel(i)

            If itemIndex = dragItem.Index Then
                Return
            End If

            'Create a copy of the item
            Dim newItem As ListViewItem = dragItem.Clone

            If CTRL Then
                'copy item
                lv.Items.Insert(itemIndex, newItem)
            Else
                'move item
                lv.Items.Insert(itemIndex, newItem)
                lv.Items.Remove(dragItem)
            End If

            itemIndex += 1 'increment insertion index for next item
        Next
    End Sub

    Private Sub lvTasks_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles lvTasks.DragEnter
        Dim lv As ListView = DirectCast(sender, ListView)
        For i As Integer = 0 To e.Data.GetFormats().Length - 1
            If e.Data.GetFormats()(i).Equals("System.Windows.Forms.ListView+SelectedListViewItemCollection") Then
                e.Effect = DragDropEffects.Move
            End If
        Next
    End Sub

    Private Sub lvTasks_ItemDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemDragEventArgs) Handles lvTasks.ItemDrag
        Dim lv As ListView = DirectCast(sender, ListView)
        If e.Button = Windows.Forms.MouseButtons.Left Then
            m_Dragging = True
            lv.DoDragDrop(lv.SelectedItems, DragDropEffects.Move)
            m_Dragging = False
        End If
    End Sub

    Private Sub lvTasks_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles lvTasks.KeyDown
        CTRL = False
    End Sub

    Private Sub lvTasks_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles lvTasks.KeyUp
        If e.KeyCode = Keys.ControlKey Then
            CTRL = True
        End If
    End Sub
#End Region

    Private Sub cmVar_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles cmVar.Opening
        Dim cm As ContextMenuStrip = DirectCast(sender, ContextMenuStrip)
        ParentTextBox = cm.SourceControl
    End Sub

    Private Sub txtBegin_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtBegin.TextChanged
        lblBegin.Text = txtBegin.Text
    End Sub

    Private Sub chkAllowPathEdit_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkAllowPathEdit.CheckedChanged, chkAllowPathEdit.EnabledChanged
        txtExtractPathText.Enabled = (chkAllowPathEdit.Checked And chkAllowPathEdit.Enabled)
        chkExtractPathShowIcon.Enabled = (chkAllowPathEdit.Checked And chkAllowPathEdit.Enabled)
    End Sub

    Private Sub txtExtractPathText_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtExtractPathText.TextChanged
        lblExtractPathText1.Text = txtExtractPathText.Text
    End Sub

    Private Sub txtInstallPath_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtInstallPath.TextChanged
        lblInstallPath.Text = txtInstallPath.Text
    End Sub

    Private Sub txtTitle_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtTitle.TextChanged
        lblTitle1.Text = txtTitle.Text
        lblTitle2.Text = txtTitle.Text
        lblTitle4.Text = txtTitle.Text
        lblTitle5.Text = txtTitle.Text
    End Sub

    Private Sub chkSilent_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkShowProgress.CheckedChanged
        txtExtractCancelText.Enabled = chkShowProgress.Checked
        txtExtractDialogText.Enabled = chkShowProgress.Checked
        txtExtractTitleText.Enabled = chkShowProgress.Checked
        cmbProgressPercent.Enabled = chkShowProgress.Checked
        chkProgressShowIcon.Enabled = chkShowProgress.Checked
        chkProgressDisableCancel.Enabled = chkShowProgress.Checked
    End Sub

    Private Sub txtCancel_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtCancel.TextChanged
        lblCancel.Text = txtCancel.Text
    End Sub

    Private Sub txtFinishMessage_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFinishMessage.TextChanged
        lblFinishMessage.Text = txtFinishMessage.Text
    End Sub

    Private Sub txtExtractCancelText_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtExtractCancelText.TextChanged
        lblExtractCancelText1.Text = txtExtractCancelText.Text
    End Sub

    Private Sub cmdAbort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAbort.Click
        Aborted = True
        If proc IsNot Nothing Then
            Try
                proc.Kill()
            Catch ex As Exception
                '
            End Try
        End If
    End Sub

    Private Sub cmbProgressPercent_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbProgressPercent.SelectedIndexChanged
        Select Case cmbProgressPercent.SelectedIndex
            Case 0
                lblProgressWindowTitle.Text = "100% " + txtExtractTitleText.Text
            Case 1
                lblProgressWindowTitle.Text = txtExtractTitleText.Text + " 100%"
            Case 2
                lblProgressWindowTitle.Text = txtExtractTitleText.Text
            Case Else
                lblProgressWindowTitle.Text = "100% " + txtExtractTitleText.Text
        End Select
    End Sub

    Private Sub txtExtractTitleText_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtExtractTitleText.TextChanged
        Select Case cmbProgressPercent.SelectedIndex
            Case 0
                lblProgressWindowTitle.Text = "100% " + txtExtractTitleText.Text
            Case 1
                lblProgressWindowTitle.Text = txtExtractTitleText.Text + " 100%"
            Case 2
                lblProgressWindowTitle.Text = txtExtractTitleText.Text
            Case Else
                lblProgressWindowTitle.Text = "100% " + txtExtractTitleText.Text
        End Select
    End Sub

    Private Sub chkHideTitleIcon_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkHideTitleIcon.CheckedChanged
        imgTitleIcon1.Visible = Not chkHideTitleIcon.Checked
        imgTitleIcon2.Visible = Not chkHideTitleIcon.Checked
        imgTitleIcon3.Visible = Not chkHideTitleIcon.Checked
        imgTitleIcon4.Visible = Not chkHideTitleIcon.Checked
        imgTitleIcon5.Visible = Not chkHideTitleIcon.Checked
    End Sub

    Private Sub chkExtractPathShowIcon_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkExtractPathShowIcon.CheckedChanged
        imgDialogIcon2.Visible = chkExtractPathShowIcon.Checked
    End Sub

    Private Sub chkProgressShowIcon_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkProgressShowIcon.CheckedChanged
        imgDialogIcon3.Visible = chkProgressShowIcon.Checked
    End Sub

    Private Sub chkPromptShowSFXIcon_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkPromptShowSFXIcon.CheckedChanged
        imgDialogIcon1.Visible = chkPromptShowSFXIcon.Checked
        imgDialogIcon4.Visible = chkPromptShowSFXIcon.Checked
        imgDialogIcon5.Visible = chkPromptShowSFXIcon.Checked
    End Sub

    Private Sub txtExtractDialogText_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtExtractDialogText.TextChanged
        lblExtractDialogText1.Text = txtExtractDialogText.Text
    End Sub
End Class
